import logging
import os
from datetime import datetime, timedelta

import jieba
import jieba.analyse
import matplotlib.pyplot as plt
import nltk
import numpy as np
import pandas as pd
import seaborn as sns
from dotenv import load_dotenv
from nltk.sentiment.vader import SentimentIntensityAnalyzer
from sqlalchemy import create_engine

# 加载环境变量
load_dotenv()

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    handlers=[logging.FileHandler("evaluation_engine.log"), logging.StreamHandler()]
)
logger = logging.getLogger("evaluation_engine")

# 获取数据库配置
DB_HOST = os.getenv('DB_HOST', 'localhost')
DB_PORT = os.getenv('DB_PORT', '3306')
DB_USER = os.getenv('DB_USER', 'root')
DB_PASSWORD = os.getenv('DB_PASSWORD', '')
DB_NAME = os.getenv('DB_NAME', 'brand_crisis')

# 加载中文情感词典（可选）
try:
    jieba.load_userdict("chinese_sentiment_dict.txt")
except:
    logger.warning("无法加载中文情感词典，将使用默认词典")

class EvaluationEngine:
    """品牌危机处理效果评估引擎"""
    
    def __init__(self, brand_name, crisis_event=None, db_connect=True):
        """
        初始化评估引擎
        
        Args:
            brand_name: 品牌名称
            crisis_event: 危机事件描述（可选）
            db_connect: 是否连接数据库
        """
        self.brand_name = brand_name
        self.crisis_event = crisis_event
        self.engine = None
        
        # 准备中文情感分析器
        # 如果是英文，可以使用nltk的SentimentIntensityAnalyzer
        try:
            nltk.download('vader_lexicon', quiet=True)
            self.sentiment_analyzer = SentimentIntensityAnalyzer()
        except:
            logger.warning("无法加载NLTK情感分析器")
            self.sentiment_analyzer = None
        
        if db_connect:
            self._connect_db()
    
    def _connect_db(self):
        """连接到MySQL数据库"""
        try:
            # 创建数据库连接
            db_url = f"mysql+pymysql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
            self.engine = create_engine(db_url)
            logger.info("数据库连接成功")
            return True
            
        except Exception as e:
            logger.error(f"数据库连接失败: {str(e)}")
            return False
    
    def generate_mock_data(self, days=30):
        """
        生成模拟危机数据用于测试和演示
        
        Args:
            days: 模拟数据的天数
            
        Returns:
            DataFrame: 模拟的危机数据
        """
        logger.info(f"正在生成{days}天的模拟危机数据")
        
        # 设置基准日期
        base_date = datetime.now() - timedelta(days=days)
        
        # 模拟数据列表
        mock_data = []
        
        # 社交媒体讨论强度曲线（模拟危机发展过程）
        # 先低后高再下降的过程
        discussion_intensity = [1, 2, 3, 2, 3, 5, 10, 25, 50, 40, 30, 25, 20, 15, 10, 8, 7, 6, 5, 4, 3, 3, 2, 2, 1, 1, 1, 1, 1, 1]
        discussion_intensity = discussion_intensity[:days]
        if len(discussion_intensity) < days:
            discussion_intensity.extend([1] * (days - len(discussion_intensity)))
        
        # 品牌正面回应日期（模拟官方回应时间点）
        response_day = 3  # 危机发生第3天做出回应
        pr_release_days = [response_day, response_day + 2, response_day + 5, response_day + 10]  # 多次回应
        
        # 模拟危机相关关键词
        crisis_keywords = ['质量问题', '缺陷', '投诉', '不满', '失败', '道歉', '召回']
        
        # 特斯拉特有危机关键词
        tesla_crisis_keywords = []
        if self.brand_name.lower() == "特斯拉" or self.brand_name.lower() == "tesla":
            tesla_crisis_keywords = ['自动驾驶', '刹车失灵', '电池起火', '车门故障', '系统故障', '安全隐患', 
                                     '突然加速', '碰撞事故', '制动系统', '车联网漏洞', '降级软件', '电池衰减']
            crisis_keywords.extend(tesla_crisis_keywords)
        
        # 小米特有危机关键词
        xiaomi_crisis_keywords = []
        if self.brand_name.lower() == "小米" or self.brand_name.lower() == "xiaomi":
            xiaomi_crisis_keywords = ['发热', '续航', '信号差', '屏幕问题', '触控失灵', '系统卡顿',
                                      '充电慢', '升级后卡顿', '拍照模糊', '闪退']
            crisis_keywords.extend(xiaomi_crisis_keywords)
        
        # 生成每天的数据
        for day in range(days):
            current_date = base_date + timedelta(days=day)
            is_response_day = day in pr_release_days
            
            # 当天的社交媒体讨论强度
            intensity = discussion_intensity[day]
            
            # 模拟社交媒体数据
            for i in range(intensity):
                # 生成不同情感倾向的内容
                if day < response_day:
                    # 危机爆发前，以负面为主
                    sentiment_score = -0.5 + np.random.normal(0, 0.2)
                elif day == response_day:
                    # 官方回应当天，情感两极分化
                    sentiment_score = 0.3 * np.random.normal(0, 1)
                else:
                    # 回应后，情感逐渐变好
                    recovery_factor = min(0.8, (day - response_day) * 0.05)
                    sentiment_score = -0.3 + recovery_factor + np.random.normal(0, 0.3)
                
                # 限制情感得分范围
                sentiment_score = max(-1.0, min(1.0, sentiment_score))
                
                # 是否为危机相关内容
                is_crisis_related = 1 if np.random.random() < 0.7 else 0
                
                # 选择危机关键词
                crisis_keyword = np.random.choice(crisis_keywords) if is_crisis_related else ''
                
                # 生成特斯拉特定内容
                content = ""
                if self.brand_name.lower() == "特斯拉" or self.brand_name.lower() == "tesla":
                    if is_crisis_related and crisis_keyword in tesla_crisis_keywords:
                        # 特斯拉危机相关内容
                        crisis_contents = [
                            f"特斯拉的{crisis_keyword}问题真的很严重，已经影响到了行车安全。",
                            f"今天在高速上我的特斯拉突然{crisis_keyword}，太可怕了！",
                            f"特斯拉在{crisis_keyword}方面的设计存在缺陷，希望厂商重视。",
                            f"多位车主反映特斯拉{crisis_keyword}问题，公司仍未给出明确解决方案。",
                            f"使用特斯拉两年了，{crisis_keyword}问题已经出现3次，非常失望。",
                            f"特斯拉的{crisis_keyword}问题在雨天尤为明显，建议大家注意安全。"
                        ]
                        content = np.random.choice(crisis_contents)
                    else:
                        # 特斯拉一般内容
                        general_contents = [
                            "特斯拉的加速性能确实很棒，但价格有点贵。",
                            "特斯拉的自动驾驶功能很好用，但还是需要密切关注路况。",
                            "特斯拉车身做工比我想象的要好，内饰简约有科技感。",
                            "充电桩越来越多了，开特斯拉出行的里程焦虑减轻了不少。",
                            "特斯拉的OTA升级很方便，车辆功能越来越丰富。",
                            "最新的特斯拉已经加入了很多新功能，使用体验不错。"
                        ]
                        content = np.random.choice(general_contents)
                # 生成小米特定内容
                elif self.brand_name.lower() == "小米" or self.brand_name.lower() == "xiaomi":
                    if is_crisis_related and crisis_keyword in xiaomi_crisis_keywords:
                        # 小米危机相关内容
                        crisis_contents = [
                            f"我的小米手机{crisis_keyword}问题很严重，影响日常使用。",
                            f"使用小米一个月，{crisis_keyword}问题已经出现多次，很失望。",
                            f"小米需要改进{crisis_keyword}方面的设计，否则会流失用户。",
                            f"论坛上很多人都反映小米{crisis_keyword}的问题，希望官方重视。",
                            f"新买的小米就出现{crisis_keyword}问题，售后服务也很差。",
                            f"小米的{crisis_keyword}问题在高负载时特别明显，影响体验。"
                        ]
                        content = np.random.choice(crisis_contents)
                    else:
                        # 小米一般内容
                        general_contents = [
                            "小米的性价比真的很高，各方面表现都不错。",
                            "MIUI系统的功能很丰富，比原生安卓好用。",
                            "小米的拍照在同价位段手机中表现不错。",
                            "小米的快充真的很方便，半小时就能充满。",
                            "小米的系统流畅度比以前好多了，很少卡顿。",
                            "小米的屏幕素质提升很大，显示效果很好。"
                        ]
                        content = np.random.choice(general_contents)
                else:
                    # 其他品牌的通用内容
                    content = f"这是关于{self.brand_name}的模拟社交媒体内容，包含关键词：{crisis_keyword}" if is_crisis_related else f"这是关于{self.brand_name}的一般讨论内容"
                
                # 添加社交媒体数据
                mock_data.append({
                    'data_type': 'social',
                    'title': f"{self.brand_name}用户讨论#{i+1}",
                    'content': content,
                    'source': f"用户{np.random.randint(1000, 9999)}",
                    'published_time': current_date + timedelta(hours=np.random.randint(0, 24)),
                    'url': f"https://social.example.com/post/{np.random.randint(10000, 99999)}",
                    'platform': np.random.choice(['微博', '知乎', '抖音']),
                    'engagement': np.random.randint(0, 500),
                    'sentiment_score': sentiment_score,
                    'crisis_related': is_crisis_related,
                    'crisis_keyword': crisis_keyword,
                    'brand_name': self.brand_name,
                    'processed_time': datetime.now()
                })
            
            # 模拟新闻报道数据（数量较少）
            if day % 3 == 0 or (day >= response_day and day <= response_day + 5):
                # 危机期间，新闻报道增加
                news_count = 2 if day >= response_day and day <= response_day + 5 else 1
                
                for i in range(news_count):
                    # 生成新闻情感（通常更客观）
                    sentiment_score = -0.3 + np.random.normal(0, 0.2)
                    
                    # 限制情感得分范围
                    sentiment_score = max(-1.0, min(1.0, sentiment_score))
                    
                    # 是否为危机相关内容
                    is_crisis_related = 1 if day >= response_day - 1 else np.random.randint(0, 2)
                    
                    # 选择危机关键词
                    crisis_keyword = np.random.choice(crisis_keywords) if is_crisis_related else ''
                    
                    # 生成特斯拉特定新闻内容
                    news_content = ""
                    news_title = ""
                    if self.brand_name.lower() == "特斯拉" or self.brand_name.lower() == "tesla":
                        if is_crisis_related:
                            # 特斯拉危机相关新闻
                            news_titles = [
                                f"特斯拉回应{crisis_keyword}问题：将进行全面排查",
                                f"多地车主反映特斯拉{crisis_keyword}故障，官方启动调查",
                                f"特斯拉发布声明承诺解决{crisis_keyword}问题",
                                f"特斯拉因{crisis_keyword}问题面临监管调查",
                                f"专家分析特斯拉{crisis_keyword}问题的技术原因"
                            ]
                            news_contents = [
                                f"近日，多位特斯拉车主反映车辆存在{crisis_keyword}问题。针对此事，特斯拉官方表示将对问题车辆进行全面排查，并承诺提供必要的技术支持和维修服务。有分析认为，此次事件可能与最新的软件更新有关。",
                                f"据多家媒体报道，特斯拉近期因{crisis_keyword}问题引发用户广泛关注。部分车主在社交媒体分享了他们的遭遇，引发了公众对电动车安全性的讨论。特斯拉方面表示正在认真对待这一问题。",
                                f"特斯拉今日针对{crisis_keyword}问题发布正式声明，称将对受影响车辆提供免费检修服务。同时，公司正在开发新的软件更新，以彻底解决这一问题。业内专家认为这是特斯拉积极履行企业责任的表现。",
                                f"由于多起与{crisis_keyword}相关的投诉，特斯拉现已面临监管部门的调查。公司CEO马斯克在社交媒体上回应称，特斯拉将全力配合调查，并保证用户的安全是公司的首要任务。"
                            ]
                            news_title = np.random.choice(news_titles)
                            news_content = np.random.choice(news_contents)
                        else:
                            # 特斯拉一般新闻
                            news_titles = [
                                "特斯拉发布新款Model Y，续航提升10%",
                                "特斯拉上海工厂产能突破50万辆",
                                "特斯拉推出新一代家用储能系统",
                                "特斯拉在华销量继续增长，市场份额扩大",
                                "特斯拉宣布新的充电网络扩张计划"
                            ]
                            news_contents = [
                                "特斯拉今日宣布新款Model Y正式上市，新车在外观设计和内饰方面进行了多项优化，同时电池续航能力提升了约10%。此举被分析师视为特斯拉巩固电动SUV市场地位的重要举措。",
                                "据特斯拉公布的最新数据，上海超级工厂年产能已突破50万辆，成为全球产能最高的电动车工厂之一。这一成绩的取得得益于特斯拉在生产效率和自动化水平方面的持续提升。",
                                "在昨日的能源产品发布会上，特斯拉推出了全新一代的Powerwall家用储能系统，新系统的存储容量和转换效率均有显著提升，将为家庭清洁能源解决方案带来更多可能。"
                            ]
                            news_title = np.random.choice(news_titles)
                            news_content = np.random.choice(news_contents)
                    # 生成小米特定新闻内容
                    elif self.brand_name.lower() == "小米" or self.brand_name.lower() == "xiaomi":
                        if is_crisis_related:
                            # 小米危机相关新闻
                            news_titles = [
                                f"用户反映小米手机{crisis_keyword}问题，官方回应",
                                f"小米手机{crisis_keyword}问题引发广泛讨论，专家解析原因",
                                f"小米发布公告解决{crisis_keyword}问题，将推送系统更新",
                                f"小米因{crisis_keyword}问题面临用户投诉增加",
                                f"分析：小米{crisis_keyword}问题的技术原因及解决方案"
                            ]
                            news_contents = [
                                f"近日，多位小米手机用户在社交平台反映设备存在{crisis_keyword}问题。针对此事，小米官方回应称已关注到相关情况，技术团队正在排查原因，将尽快通过系统更新解决这一问题。",
                                f"小米手机近期因{crisis_keyword}问题引发用户讨论。据用户反馈，这一问题主要出现在特定使用场景下，影响了部分用户的体验。小米方面表示正在积极处理相关反馈。",
                                f"小米今日发布公告，针对用户反映的{crisis_keyword}问题，将在近期推送系统更新进行修复。公司表示，解决用户问题是小米的首要任务，将持续优化产品体验。",
                                f"据消费者协会数据显示，小米近期因{crisis_keyword}相关问题的投诉有所增加。小米方面已经成立专项小组，与用户保持沟通，并承诺提供妥善的解决方案。"
                            ]
                            news_title = np.random.choice(news_titles)
                            news_content = np.random.choice(news_contents)
                        else:
                            # 小米一般新闻
                            news_titles = [
                                "小米发布新款旗舰手机，搭载自研芯片",
                                "小米IoT设备销量突破3亿台",
                                "小米宣布进军电动汽车市场",
                                "小米全球市场份额持续增长",
                                "小米推出新一代快充技术"
                            ]
                            news_contents = [
                                "小米今日举行新品发布会，正式推出新一代旗舰手机。新机搭载小米自研的处理器，在性能和能效方面均有显著提升，同时拍照和充电能力也得到强化。",
                                "小米集团发布的最新数据显示，其IoT设备全球累计销量已超过3亿台，覆盖智能家居、健康监测、环境电器等多个领域，构建了完整的智能生态系统。",
                                "在昨日的战略发布会上，小米正式宣布进军电动汽车领域，计划未来十年投入100亿美元，打造集智能驾驶和智能座舱于一体的新一代智能电动汽车。"
                            ]
                            news_title = np.random.choice(news_titles)
                            news_content = np.random.choice(news_contents)
                    else:
                        # 其他品牌的通用新闻内容
                        news_title = f"{self.brand_name}相关新闻报道#{day*2+i}"
                        news_content = f"这是关于{self.brand_name}的模拟新闻报道，报道了{crisis_keyword}相关内容" if is_crisis_related else f"这是关于{self.brand_name}的一般新闻报道"
                    
                    # 添加新闻数据
                    mock_data.append({
                        'data_type': 'news',
                        'title': news_title,
                        'content': news_content,
                        'source': np.random.choice(['新浪科技', '腾讯科技', '网易科技', '凤凰科技']),
                        'published_time': current_date + timedelta(hours=np.random.randint(8, 20)),
                        'url': f"https://news.example.com/article/{np.random.randint(10000, 99999)}",
                        'platform': '新闻媒体',
                        'engagement': np.random.randint(100, 1000),
                        'sentiment_score': sentiment_score,
                        'crisis_related': is_crisis_related,
                        'crisis_keyword': crisis_keyword,
                        'brand_name': self.brand_name,
                        'processed_time': datetime.now()
                    })
            
            # 模拟官方声明数据
            if is_response_day:
                # 发布官方声明
                response_tone = 0.2 + min(0.6, (day - response_day) * 0.1) + np.random.normal(0, 0.1)
                
                # 特斯拉官方声明
                statement_title = ""
                statement_content = ""
                if self.brand_name.lower() == "特斯拉" or self.brand_name.lower() == "tesla":
                    # 根据危机阶段选择合适的声明标题和内容
                    if day == response_day:  # 初始回应
                        statement_titles = [
                            "特斯拉关于近期用户反馈的声明",
                            "特斯拉就车辆安全问题发布官方声明",
                            f"关于{self.crisis_event or '近期用户反馈'}的说明"
                        ]
                        statement_contents = [
                            f"特斯拉始终将用户安全放在首位。我们注意到近期有用户反馈{self.crisis_event or '某些使用问题'}，我们正在认真对待每一条反馈，并已组织技术团队进行全面排查。特斯拉承诺为用户提供最安全、最可靠的产品和服务。",
                            f"特斯拉已关注到用户反映的{self.crisis_event or '产品问题'}，我们深感重视。目前技术团队正在对相关情况进行紧急调查，我们将在查明原因后及时向用户和公众通报调查结果。特斯拉始终秉持透明、负责任的态度处理每一个安全相关问题。",
                            f"我们已收到关于{self.crisis_event or '车辆问题'}的反馈，特斯拉对此高度重视。我们正在收集相关信息并进行技术分析，同时与相关用户保持密切沟通。特斯拉将尽快给出明确的解决方案。"
                        ]
                    elif day == response_day + 2:  # 进一步说明
                        statement_titles = [
                            "特斯拉公布初步调查结果",
                            "特斯拉技术团队关于近期问题的分析",
                            "特斯拉更新关于用户反馈问题的处理进展"
                        ]
                        statement_contents = [
                            f"经过初步技术分析，我们发现部分用户反映的{self.crisis_event or '问题'}与最新版本的软件更新可能存在关联。特斯拉已经确定了可能的原因，并正在开发修复方案。我们预计将在一周内推送软件更新，以解决这一问题。同时，我们建议用户在驾驶过程中保持警觉，确保安全。",
                            f"特斯拉技术团队已对{self.crisis_event or '反馈问题'}进行了深入分析，初步确定这是由于特定工作环境下的软硬件交互引起的。目前我们已有明确的解决思路，正在进行方案验证。特斯拉将继续与受影响的用户保持沟通，并提供必要的技术支持。",
                            f"关于近期{self.crisis_event or '用户反馈的问题'}，我们已经缩小了问题的范围和可能的原因。特斯拉将在近期启动针对性的服务活动，为可能受影响的车辆提供检测和必要的调整。用户可通过特斯拉App或致电服务中心预约相关服务。"
                        ]
                    else:  # 后续处理和总结
                        statement_titles = [
                            "特斯拉发布问题解决方案",
                            "特斯拉完成技术优化并启动服务计划",
                            "特斯拉总结近期问题处理及改进措施"
                        ]
                        statement_contents = [
                            f"针对{self.crisis_event or '之前反馈的问题'}，特斯拉已完成全面技术验证，并推出了完整的解决方案。从今日起，我们将通过OTA方式向所有车辆推送软件更新，该更新将彻底解决已发现的问题。同时，特斯拉服务中心也已准备就绪，可为有需要的用户提供额外的硬件检测服务。我们感谢用户的耐心等待和理解。",
                            f"特斯拉已完成针对{self.crisis_event or '用户反馈问题'}的技术优化工作。最新的软件版本已于昨日开始逐步推送，同时我们也启动了主动服务计划，将通过短信或App通知可能受影响的用户。此外，特斯拉还优化了质量控制流程，确保类似问题不再发生。",
                            f"通过对{self.crisis_event or '近期问题'}的调查和处理，特斯拉不仅解决了技术层面的具体问题，也发现了产品开发和测试环节的优化空间。我们已经调整了研发流程，增强了极端条件下的测试强度，并改进了用户反馈的收集和处理机制。特斯拉将继续努力，为用户提供卓越的产品体验。"
                        ]
                    
                    statement_title = np.random.choice(statement_titles)
                    statement_content = np.random.choice(statement_contents)
                # 小米官方声明
                elif self.brand_name.lower() == "小米" or self.brand_name.lower() == "xiaomi":
                    # 根据危机阶段选择合适的声明标题和内容
                    if day == response_day:  # 初始回应
                        statement_titles = [
                            "小米关于用户反馈问题的声明",
                            "小米官方回应产品使用问题",
                            f"关于{self.crisis_event or '近期用户反馈'}的说明"
                        ]
                        statement_contents = [
                            f"小米始终关注用户体验。我们注意到近期有用户反馈关于{self.crisis_event or '产品使用'}的问题，我们正在认真收集和分析这些反馈。小米技术团队已经启动调查，我们将尽快给出解决方案。",
                            f"针对用户反映的{self.crisis_event or '产品问题'}，小米高度重视并深表歉意。我们已组织工程师团队对问题进行分析，初步判断与最新系统版本有关。我们将尽快通过系统更新解决这一问题。",
                            f"我们已收到关于{self.crisis_event or '产品使用'}的反馈，小米对此高度重视。目前我们正在分析问题原因，并与相关用户保持沟通。小米会尽快提供解决方案，感谢用户的理解和支持。"
                        ]
                    elif day == response_day + 2:  # 进一步说明
                        statement_titles = [
                            "小米公布问题排查进展",
                            "小米MIUI团队关于系统问题的分析",
                            "小米更新关于用户反馈问题的处理进展"
                        ]
                        statement_contents = [
                            f"经过技术团队的排查，我们已经确定{self.crisis_event or '用户反馈问题'}的原因。这一问题主要与MIUI最新版本中的特定功能模块有关。我们已经开发出修复方案，将在未来3天内通过OTA方式推送更新。同时，我们也已经在新版本开发中加强了测试环节，避免类似问题再次发生。",
                            f"小米MIUI团队已对{self.crisis_event or '系统问题'}进行了深入分析，确定这是由于系统资源调度在特定场景下的优化不足导致的。修复版本已经完成内部测试，我们将尽快向用户推送。感谢用户的耐心等待。",
                            f"关于近期{self.crisis_event or '用户反馈的问题'}，我们已制定明确的解决方案。新版系统将优化{self.crisis_event or '相关功能'}的性能表现，同时我们也在用户反馈渠道做了改进，使问题能更快得到响应和解决。"
                        ]
                    else:  # 后续处理和总结
                        statement_titles = [
                            "小米发布系统更新解决用户反馈问题",
                            "小米完成问题修复并优化用户体验",
                            "小米总结问题处理经验并宣布改进措施"
                        ]
                        statement_contents = [
                            f"针对{self.crisis_event or '此前反馈的问题'}，小米已正式推送系统更新。此次更新不仅解决了用户反馈的具体问题，还对整体系统性能做了优化。我们建议用户及时更新到最新版本。小米始终致力于为用户提供最好的产品体验，再次感谢广大用户的支持与理解。",
                            f"小米已通过系统更新解决了{self.crisis_event or '用户反馈的问题'}。同时，我们也从这次事件中吸取了经验，优化了产品测试流程和用户反馈机制。小米将继续秉持'以用户为中心'的理念，不断提升产品和服务质量。",
                            f"通过处理此次{self.crisis_event or '用户反馈问题'}，小米重新审视了产品开发流程。我们已增加测试环节的覆盖面，并成立专门的用户体验改进小组，确保类似问题能在产品发布前被发现和解决。小米感谢用户一直以来的支持与建议，我们将不断进步。"
                        ]
                    
                    statement_title = np.random.choice(statement_titles)
                    statement_content = np.random.choice(statement_contents)
                else:
                    # 其他品牌的通用声明
                    statement_title = f"{self.brand_name}官方声明：关于{self.crisis_event or '近期问题'}的说明"
                    statement_content = f"这是{self.brand_name}关于{self.crisis_event or '近期问题'}的官方声明。我们重视每一位用户的反馈，正在积极解决问题。我们承诺将{np.random.choice(['改进产品', '优化服务', '加强质量控制', '提供补偿'])}。"
                
                mock_data.append({
                    'data_type': 'official',
                    'title': statement_title,
                    'content': statement_content,
                    'source': f"{self.brand_name}官方",
                    'published_time': current_date + timedelta(hours=np.random.randint(9, 16)),
                    'url': f"https://official.example.com/statement/{np.random.randint(1000, 9999)}",
                    'platform': np.random.choice(['官方网站', '官方微博']),
                    'engagement': np.random.randint(1000, 5000),
                    'sentiment_score': response_tone,
                    'crisis_related': 1,
                    'crisis_keyword': np.random.choice(crisis_keywords),
                    'brand_name': self.brand_name,
                    'processed_time': datetime.now()
                })
        
        # 转换为DataFrame
        mock_df = pd.DataFrame(mock_data)
        
        # 添加日期列，方便按日期分析
        mock_df['date'] = pd.to_datetime(mock_df['published_time']).dt.date
        
        # 添加自危机开始的天数
        min_date = mock_df['date'].min()
        mock_df['days_since_start'] = (mock_df['date'] - min_date).dt.days
        
        logger.info(f"已生成模拟危机数据：{len(mock_df)}条记录")
        return mock_df
    
    def load_crisis_data(self, start_date=None, end_date=None, from_excel=None):
        """
        加载危机数据
        
        Args:
            start_date: 开始日期，格式为'YYYY-MM-DD'（可选）
            end_date: 结束日期，格式为'YYYY-MM-DD'（可选）
            from_excel: Excel文件路径，如果提供则从Excel加载数据而不是数据库
            
        Returns:
            加载的数据量
        """
        try:
            if from_excel and os.path.exists(from_excel):
                # 从Excel加载数据
                self.crisis_data = pd.read_excel(from_excel)
                logger.info(f"从Excel文件 {from_excel} 加载了 {len(self.crisis_data)} 条数据")
            elif self.engine:
                # 从数据库加载数据
                # 构建查询
                query = f"""
                SELECT * FROM crisis_data
                WHERE brand_name = '{self.brand_name}'
                """
                
                # 添加日期过滤条件
                if start_date:
                    query += f" AND published_time >= '{start_date}'"
                if end_date:
                    query += f" AND published_time <= '{end_date}'"
                
                # 排序
                query += " ORDER BY published_time ASC"
                
                # 执行查询
                try:
                    self.crisis_data = pd.read_sql(query, self.engine)
                    logger.info(f"从数据库加载了 {len(self.crisis_data)} 条关于 {self.brand_name} 的数据")
                except Exception as db_error:
                    logger.error(f"从数据库加载数据失败: {str(db_error)}，将使用模拟数据")
                    self.crisis_data = self.generate_mock_data()
            else:
                # 无法从数据库加载，使用模拟数据
                logger.warning("数据库未连接，将使用模拟数据")
                self.crisis_data = self.generate_mock_data()
            
            # 如果没有数据，使用模拟数据
            if not hasattr(self, 'crisis_data') or self.crisis_data.empty:
                logger.warning("未找到实际数据，将使用模拟数据")
                self.crisis_data = self.generate_mock_data()
            
            # 数据预处理
            self._preprocess_data()
            
            return len(self.crisis_data)
            
        except Exception as e:
            logger.error(f"加载危机数据出错: {str(e)}，将使用模拟数据")
            self.crisis_data = self.generate_mock_data()
            self._preprocess_data()
            return len(self.crisis_data)
    
    def _preprocess_data(self):
        """对加载的数据进行预处理"""
        try:
            # 确保日期列是datetime类型
            if 'published_time' in self.crisis_data.columns:
                self.crisis_data['published_time'] = pd.to_datetime(self.crisis_data['published_time'], errors='coerce')
                self.crisis_data['date'] = self.crisis_data['published_time'].dt.date
            
            # 添加情感得分列（如果不存在）
            if 'sentiment_score' not in self.crisis_data.columns or self.crisis_data['sentiment_score'].sum() == 0:
                self.crisis_data['sentiment_score'] = self.crisis_data['content'].apply(lambda x: self._analyze_sentiment(x) if pd.notna(x) else 0)
            
            # 给数据添加日期组（用于时间序列分析）
            if 'date' in self.crisis_data.columns:
                min_date = self.crisis_data['date'].min()
                self.crisis_data['days_since_start'] = (self.crisis_data['date'] - min_date).dt.days
            
            logger.info("数据预处理完成")
            
        except Exception as e:
            logger.error(f"数据预处理出错: {str(e)}")
    
    def _analyze_sentiment(self, text):
        """
        分析文本情感
        
        Args:
            text: 要分析的文本
            
        Returns:
            情感得分：-1（极负面）到1（极正面）
        """
        if not text or not isinstance(text, str):
            return 0
        
        if self.sentiment_analyzer:
            # 使用NLTK情感分析器
            try:
                scores = self.sentiment_analyzer.polarity_scores(text)
                return scores['compound']  # compound是综合得分，范围从-1到1
            except:
                logger.warning("NLTK情感分析失败，使用简单规则")
        
        # 简单的基于规则的中文情感分析（备选方案）
        try:
            # 正面情感词
            positive_words = ['好', '优秀', '满意', '赞', '支持', '喜欢', '感谢', '快速', '及时', '解决', '有效', '正面', '满意度']
            # 负面情感词
            negative_words = ['差', '糟糕', '不满', '投诉', '问题', '缺陷', '失败', '拖延', '欺骗', '虚假', '召回', '退款', '负面']
            
            # 计算情感词出现次数
            pos_count = sum([text.count(word) for word in positive_words])
            neg_count = sum([text.count(word) for word in negative_words])
            
            # 计算情感得分
            total = pos_count + neg_count
            if total == 0:
                return 0
            
            return (pos_count - neg_count) / total
            
        except Exception as e:
            logger.error(f"情感分析出错: {str(e)}")
            return 0
    
    def evaluate_response_speed(self):
        """
        评估品牌危机响应速度
        
        Returns:
            响应速度评估结果，包括响应时间、评分和建议
        """
        if not hasattr(self, 'crisis_data') or self.crisis_data.empty:
            logger.error("未加载数据，无法评估")
            return {
                'response_time_hours': None,
                'response_speed_score': 0,
                'recommendation': "无法评估响应速度，请先加载数据"
            }
        
        try:
            # 筛选出危机相关内容
            crisis_content = self.crisis_data[self.crisis_data['crisis_related'] == 1]
            
            # 如果没有危机相关内容，返回默认值
            if crisis_content.empty:
                return {
                    'response_time_hours': None,
                    'response_speed_score': 0,
                    'recommendation': "未发现危机相关内容，无法评估响应速度"
                }
            
            # 找出第一条负面消息
            first_negative_post = crisis_content.sort_values('published_time').iloc[0]
            
            # 找出官方回应
            official_responses = self.crisis_data[
                (self.crisis_data['data_type'] == 'official') & 
                (self.crisis_data['published_time'] >= first_negative_post['published_time'])
            ]
            
            # 如果没有官方回应，返回最低评分
            if official_responses.empty:
                return {
                    'response_time_hours': None,
                    'response_speed_score': 0,
                    'recommendation': "品牌未对危机做出官方回应，建议建立快速响应机制"
                }
            
            # 找出第一条官方回应
            first_response = official_responses.sort_values('published_time').iloc[0]
            
            # 计算响应时间（小时）
            response_time = (first_response['published_time'] - first_negative_post['published_time']).total_seconds() / 3600
            
            # 评分规则（根据行业标准调整）
            # 0-2小时：5分（优秀）
            # 2-6小时：4分（良好）
            # 6-12小时：3分（一般）
            # 12-24小时：2分（较差）
            # 24小时以上：1分（很差）
            score = 0
            recommendation = ""
            
            if response_time <= 2:
                score = 5
                recommendation = "品牌响应速度优秀，及时控制了危机扩散"
            elif response_time <= 6:
                score = 4
                recommendation = "品牌响应速度良好，基本控制了危机扩散"
            elif response_time <= 12:
                score = 3
                recommendation = "品牌响应速度一般，对危机控制有一定延迟"
            elif response_time <= 24:
                score = 2
                recommendation = "品牌响应速度较慢，危机已经扩散，建议优化响应流程"
            else:
                score = 1
                recommendation = "品牌响应速度很慢，危机已广泛扩散，建议建立快速响应机制并进行危机处理培训"
            
            return {
                'response_time_hours': response_time,
                'response_speed_score': score,
                'recommendation': recommendation
            }
            
        except Exception as e:
            logger.error(f"评估响应速度出错: {str(e)}")
            return {
                'response_time_hours': None,
                'response_speed_score': 0,
                'recommendation': f"评估过程出错: {str(e)}"
            }
    
    def evaluate_transparency(self):
        """
        评估品牌危机沟通透明度
        
        Returns:
            透明度评估结果，包括透明度评分和建议
        """
        if not hasattr(self, 'crisis_data') or self.crisis_data.empty:
            logger.error("未加载数据，无法评估")
            return {
                'transparency_score': 0,
                'recommendation': "无法评估透明度，请先加载数据"
            }
        
        try:
            # 获取官方声明
            official_statements = self.crisis_data[self.crisis_data['data_type'] == 'official']
            
            # 如果没有官方声明，返回最低评分
            if official_statements.empty:
                return {
                    'transparency_score': 0,
                    'recommendation': "未发现官方声明，无法评估透明度，建议品牌发布正式声明"
                }
            
            # 透明度评估标准
            transparency_indicators = [
                "承认", "道歉", "说明", "原因", "详细", "公开", "调查", "结果", 
                "改进", "措施", "补偿", "赔偿", "退款", "责任", "问题"
            ]
            
            # 计算每条声明的透明度指标
            transparency_scores = []
            
            for _, statement in official_statements.iterrows():
                content = statement['content'] if pd.notna(statement['content']) else ""
                title = statement['title'] if pd.notna(statement['title']) else ""
                
                # 合并标题和内容
                full_text = title + " " + content
                
                # 统计透明度指标
                indicator_count = sum([1 for indicator in transparency_indicators if indicator in full_text])
                
                # 文本长度评分（较长的声明通常包含更多细节）
                length_score = min(len(full_text) / 500, 1.0)  # 标准化，最高1分
                
                # 计算透明度得分
                transparency_score = (indicator_count / len(transparency_indicators) * 0.7) + (length_score * 0.3)
                transparency_scores.append(transparency_score)
            
            # 计算平均透明度得分（满分为1）
            avg_transparency = np.mean(transparency_scores) if transparency_scores else 0
            
            # 转换为5分制
            transparency_score = round(avg_transparency * 5, 1)
            
            # 生成建议
            if transparency_score >= 4:
                recommendation = "品牌沟通透明度高，公开了危机详情并承担责任"
            elif transparency_score >= 3:
                recommendation = "品牌沟通透明度良好，但可以提供更多细节和后续措施"
            elif transparency_score >= 2:
                recommendation = "品牌沟通透明度一般，建议提供更多危机细节并说明解决方案"
            else:
                recommendation = "品牌沟通透明度低，建议公开承认问题，详细说明原因和补救措施"
            
            return {
                'transparency_score': transparency_score,
                'recommendation': recommendation
            }
            
        except Exception as e:
            logger.error(f"评估透明度出错: {str(e)}")
            return {
                'transparency_score': 0,
                'recommendation': f"评估过程出错: {str(e)}"
            }
    
    def evaluate_brand_image_protection(self):
        """
        评估品牌形象保护效果
        
        Returns:
            品牌形象保护评估结果，包括情感变化评分和建议
        """
        if not hasattr(self, 'crisis_data') or self.crisis_data.empty:
            logger.error("未加载数据，无法评估")
            return {
                'image_protection_score': 0,
                'sentiment_change': 0,
                'recommendation': "无法评估品牌形象保护效果，请先加载数据"
            }
        
        try:
            # 确保数据按时间排序
            self.crisis_data = self.crisis_data.sort_values('published_time')
            
            # 将数据分为三个阶段：危机前、危机中、危机后
            # 假设数据已按时间排序，我们找出官方回应的时间作为分界点
            official_responses = self.crisis_data[self.crisis_data['data_type'] == 'official']
            
            if official_responses.empty:
                return {
                    'image_protection_score': 0,
                    'sentiment_change': 0,
                    'recommendation': "未发现官方回应，无法评估品牌形象保护效果"
                }
            
            # 第一条官方回应的时间
            first_response_time = official_responses['published_time'].min()
            
            # 最后一条官方回应的时间
            last_response_time = official_responses['published_time'].max()
            
            # 危机前：首条官方回应前7天
            pre_crisis_start = first_response_time - timedelta(days=7)
            pre_crisis_data = self.crisis_data[
                (self.crisis_data['published_time'] >= pre_crisis_start) & 
                (self.crisis_data['published_time'] < first_response_time)
            ]
            
            # 危机中：首条回应至最后一条回应
            during_crisis_data = self.crisis_data[
                (self.crisis_data['published_time'] >= first_response_time) & 
                (self.crisis_data['published_time'] <= last_response_time)
            ]
            
            # 危机后：最后一条官方回应后7天
            post_crisis_end = last_response_time + timedelta(days=7)
            post_crisis_data = self.crisis_data[
                (self.crisis_data['published_time'] > last_response_time) & 
                (self.crisis_data['published_time'] <= post_crisis_end)
            ]
            
            # 计算各阶段平均情感得分
            pre_crisis_sentiment = pre_crisis_data['sentiment_score'].mean() if not pre_crisis_data.empty else 0
            during_crisis_sentiment = during_crisis_data['sentiment_score'].mean() if not during_crisis_data.empty else 0
            post_crisis_sentiment = post_crisis_data['sentiment_score'].mean() if not post_crisis_data.empty else 0
            
            # 计算情感变化
            sentiment_change = post_crisis_sentiment - pre_crisis_sentiment
            
            # 评估品牌形象保护效果（满分为5）
            score = 0
            recommendation = ""
            
            if sentiment_change >= 0.2:
                score = 5
                recommendation = "品牌形象保护效果优秀，危机后情感显著提升，说明危机处理非常成功"
            elif sentiment_change >= 0.1:
                score = 4
                recommendation = "品牌形象保护效果良好，危机后情感有所提升，危机处理成功"
            elif sentiment_change >= 0:
                score = 3
                recommendation = "品牌形象保护效果一般，危机后情感基本恢复，但未见显著提升"
            elif sentiment_change >= -0.1:
                score = 2
                recommendation = "品牌形象保护效果较差，危机后情感略有下降，建议加强后续公关措施"
            else:
                score = 1
                recommendation = "品牌形象保护效果很差，危机后情感显著下降，建议重新评估危机处理策略并加强补救措施"
            
            return {
                'image_protection_score': score,
                'sentiment_change': sentiment_change,
                'pre_crisis_sentiment': pre_crisis_sentiment,
                'during_crisis_sentiment': during_crisis_sentiment,
                'post_crisis_sentiment': post_crisis_sentiment,
                'recommendation': recommendation
            }
            
        except Exception as e:
            logger.error(f"评估品牌形象保护效果出错: {str(e)}")
            return {
                'image_protection_score': 0,
                'sentiment_change': 0,
                'recommendation': f"评估过程出错: {str(e)}"
            }
    
    def generate_comprehensive_score(self):
        """
        生成危机处理综合评分
        
        Returns:
            综合评分和总体评估
        """
        # 评估响应速度
        response_speed = self.evaluate_response_speed()
        
        # 评估沟通透明度
        transparency = self.evaluate_transparency()
        
        # 评估品牌形象保护
        image_protection = self.evaluate_brand_image_protection()
        
        # 计算综合得分（各占权重）
        response_speed_weight = 0.3
        transparency_weight = 0.3
        image_protection_weight = 0.4
        
        comprehensive_score = (
            response_speed['response_speed_score'] * response_speed_weight +
            transparency['transparency_score'] * transparency_weight +
            image_protection['image_protection_score'] * image_protection_weight
        )
        
        # 生成总体评估
        overall_assessment = ""
        if comprehensive_score >= 4.5:
            overall_assessment = "优秀"
        elif comprehensive_score >= 3.5:
            overall_assessment = "良好"
        elif comprehensive_score >= 2.5:
            overall_assessment = "一般"
        elif comprehensive_score >= 1.5:
            overall_assessment = "较差"
        else:
            overall_assessment = "很差"
        
        return {
            'comprehensive_score': round(comprehensive_score, 1),
            'response_speed_score': response_speed['response_speed_score'],
            'transparency_score': transparency['transparency_score'],
            'image_protection_score': image_protection['image_protection_score'],
            'overall_assessment': overall_assessment,
            'response_speed_recommendation': response_speed['recommendation'],
            'transparency_recommendation': transparency['recommendation'],
            'image_protection_recommendation': image_protection['recommendation']
        }
    
    def plot_sentiment_trend(self, output_file='sentiment_trend.png'):
        """
        绘制情感趋势图
        
        Args:
            output_file: 输出文件路径
            
        Returns:
            图表生成是否成功
        """
        if not hasattr(self, 'crisis_data') or self.crisis_data.empty:
            logger.error("未加载数据，无法绘制情感趋势图")
            return False
        
        try:
            # 按日期分组计算平均情感得分
            daily_sentiment = self.crisis_data.groupby('date')['sentiment_score'].mean().reset_index()
            
            # 绘制趋势图
            plt.figure(figsize=(12, 6))
            sns.lineplot(x='date', y='sentiment_score', data=daily_sentiment, marker='o')
            
            # 标记官方回应
            official_responses = self.crisis_data[self.crisis_data['data_type'] == 'official']
            if not official_responses.empty:
                official_dates = official_responses['date'].unique()
                for date in official_dates:
                    plt.axvline(x=date, color='red', linestyle='--', alpha=0.7)
            
            plt.title(f'{self.brand_name} 危机期间情感趋势')
            plt.xlabel('日期')
            plt.ylabel('情感得分 (-1到1)')
            plt.grid(True, alpha=0.3)
            plt.tight_layout()
            
            # 保存图表
            plt.savefig(output_file)
            plt.close()
            
            logger.info(f"情感趋势图已保存到 {output_file}")
            return True
            
        except Exception as e:
            logger.error(f"绘制情感趋势图出错: {str(e)}")
            return False
    
    def generate_evaluation_report(self, output_file='crisis_evaluation_report.xlsx'):
        """
        生成评估报告
        
        Args:
            output_file: 输出Excel文件路径
            
        Returns:
            评估报告生成是否成功
        """
        try:
            # 生成综合评分
            results = self.generate_comprehensive_score()
            
            # 创建Excel报告
            report_data = {
                '评估项目': ['综合得分', '响应速度', '沟通透明度', '品牌形象保护', '总体评估'],
                '评分': [
                    results['comprehensive_score'],
                    results['response_speed_score'],
                    results['transparency_score'],
                    results['image_protection_score'],
                    results['overall_assessment']
                ],
                '建议': [
                    '综合以下各项建议',
                    results['response_speed_recommendation'],
                    results['transparency_recommendation'],
                    results['image_protection_recommendation'],
                    f"{self.brand_name}危机处理整体表现{results['overall_assessment']}，综合得分为{results['comprehensive_score']}分（满分5分）"
                ]
            }
            
            # 创建DataFrame
            report_df = pd.DataFrame(report_data)
            
            # 保存到Excel
            report_df.to_excel(output_file, index=False, sheet_name='评估结果')
            
            logger.info(f"评估报告已保存到 {output_file}")
            return True
            
        except Exception as e:
            logger.error(f"生成评估报告出错: {str(e)}")
            return False
    
    def extract_key_topics(self, top_n=10):
        """
        提取危机中的关键话题
        
        Args:
            top_n: 返回的关键词数量
            
        Returns:
            关键话题及其频率
        """
        if not hasattr(self, 'crisis_data') or self.crisis_data.empty:
            logger.error("未加载数据，无法提取关键话题")
            return {}
        
        try:
            # 合并所有相关内容
            all_content = " ".join(self.crisis_data['content'].dropna().astype(str))
            
            # 使用jieba提取关键词
            keywords = jieba.analyse.extract_tags(all_content, topK=top_n, withWeight=True)
            
            # 转换为字典格式
            topics = {word: float(weight) for word, weight in keywords}
            
            return topics
            
        except Exception as e:
            logger.error(f"提取关键话题出错: {str(e)}")
            return {}

if __name__ == "__main__":
    # 测试代码
    engine = EvaluationEngine("小米", "小米手机发热问题")
    
    # 加载数据
    engine.load_crisis_data(from_excel="output/小米_integrated_crisis_data.xlsx")
    
    # 评估响应速度
    response_speed = engine.evaluate_response_speed()
    print(f"响应速度评分: {response_speed['response_speed_score']}")
    print(f"建议: {response_speed['recommendation']}")
    
    # 评估沟通透明度
    transparency = engine.evaluate_transparency()
    print(f"沟通透明度评分: {transparency['transparency_score']}")
    print(f"建议: {transparency['recommendation']}")
    
    # 评估品牌形象保护
    image_protection = engine.evaluate_brand_image_protection()
    print(f"品牌形象保护评分: {image_protection['image_protection_score']}")
    print(f"建议: {image_protection['recommendation']}")
    
    # 生成综合评分
    comprehensive = engine.generate_comprehensive_score()
    print(f"综合评分: {comprehensive['comprehensive_score']}")
    print(f"总体评估: {comprehensive['overall_assessment']}")
    
    # 绘制情感趋势图
    engine.plot_sentiment_trend("output/小米_sentiment_trend.png")
    
    # 生成评估报告
    engine.generate_evaluation_report("output/小米_crisis_evaluation_report.xlsx") 